<?php
/*
 * 邮件群发类
 */
include("../config/config.inc.php");
include("../config/QuickMySQL.php");
include("../config/function.inc.php");
include("./../class/class.phpmailer.php");

class CCrontabSendEmail
{
	public $mysql = null;
	public $lockfile = "";
	public $subject = "";
	public $subjects = array();
	public $subjecti = 0;
	public $body = "";
	public $from = "";
	public $name = "";
	public $smtp = "";
	public $usr = "";
	public $pwd = "";
	public $port = 0;
	/* 构造函数 */
	function __construct() {
		$this->mysql = new QuickMySQL();
		$this->lockfile = dirname(__FILE__) . "/../lock/crontab-sendemail";
		if( isset($_GET["id"]) ){
			$id = (int)$_GET["id"];
			$this->lockfile .= "-{$id}";
			$fp = fopen($this->lockfile, "w");
			if( !$fp ){
				$this->DbgPrint("打开文件{$this->lockfile}失败");
				return;
			}
			if( !flock($fp, LOCK_EX | LOCK_NB) ){
				$this->DbgPrint("锁定文件{$this->lockfile}失败");
				return;
			}
			$this->DbgPrint("启动邮件队列{$id}");
			try{
				$this->OnStartSend($id);
			} catch (Exception $e){
				DbgPrint($this->logfile, "发送邮件{$id}操作出现异常" . $e->getMessage());
			}
			$this->DbgPrint("完成邮件队列{$id}");
			// 退出
			flock($fp, LOCK_UN);
			fclose($fp);
			unlink($this->lockfile);
		} else {
			$this->DbgPrint("定时启动");
			$this->OnEnumSend();
		}
	}
	/* 枚举发送 */
	function OnEnumSend(){
		/*$sql = "select id from t_sendemail_group where sm_flag > 0 and sm_flag < 32 "
			. " and 0 <> sm_run and date_sub(now(), interval sm_interval minute) > ifnull(sm_lastdt, 0); ";
		*/
		$sql = "select id from t_sendemail_group where sm_flag > 0 and sm_flag < 32 "
			. " and 0 <> sm_run; ";
		$res = $this->mysql->Query($sql);
		while( $row = mysql_fetch_row($res) ){
			/*if( 1 == VerifyEmail("914910235@qq.com") ){
				$this->DbgPrint("正被QQ服务器锁定");
				break;
			}*/
			$this->OpenUrl((int)$row[0]);
		}
		mysql_free_result($res);
	}
	/* 开始发送 */
	function OnStartSend($id){
		// 获取信息
		$sql = "select a.sm_to, a.sm_subject, a.sm_flag, a.sm_max, a.sm_body, b.addr, b.name, "
			. " b.smtp, b.user, b.pwd, b.port from t_sendemail_group as a left join t_email_list as b "
			. " on a.m_no = b.id where a.id = {$id}";
		$res = $this->mysql->Query($sql);
		if( !($row = mysql_fetch_row($res)) ){
			$this->DbgPrint("找不到id为{$id}的数据");
			return;
		}
		$sm_to = $row[0];
		$this->subject = $row[1];
		$this->subjects = split(";", $row[1]);
		$sm_flag = 0;
		if( (int)$row[2] < 32 && (int)$row[2] > 0)
			$sm_flag = 1 << (int)$row[2];
		$sm_max = (int)$row[3];
		$this->body = $row[4];
		$this->from = $row[5];
		$this->name = $row[6];
		$this->smtp = $row[7];
		$this->usr = $row[8];
		$this->pwd = $row[9];
		$this->port = (int)$row[10];
		mysql_free_result($res);
		if( 0 == $sm_flag ){
			$this->DbgPrint("id为{$id}的标识非法");
			return;
		}
		// 暂时将Max设为500
		if($sm_max > 100)
			$sm_max = 100;
		// 发送邮件
		$this->mysql->Query("update t_sendemail_group set sm_firstdt = now() where id={$id} and sm_firstdt is null");
		$this->mysql->Query("update t_sendemail_group set sm_lastdt = now() where id={$id}");
		// 开始执行
		$sql = "select id, email,qq,name,license,curdate() from {$sm_to} where 0 = (sem_n & {$sm_flag}) limit {$sm_max}";
		$res = $this->mysql->Query($sql);
		if( 0 == mysql_num_rows($res) ){
			// 没有发送队列时自动暂停
			$this->mysql->Query("update t_sendemail_group set sm_run=1 where id = {$id}");
			mysql_free_result($res);
			return;
		}
		while( $row = mysql_fetch_row($res) ){
			if( $this->SendEmail($row[1], $row[2], $row[3], $row[4], $row[5]) ){
				$this->mysql->Query("update t_sendemail_group set sm_success = sm_success + 1 where id = {$id}");
				$this->mysql->Query("update {$sm_to} set sem_s = sem_s + 1 where id = {$row[0]}");
			} else {
				$this->mysql->Query("update t_sendemail_group set sm_failure = sm_failure + 1 where id = {$id}");
				$this->mysql->Query("update {$sm_to} set sem_f = sem_f + 1 where id = {$row[0]}");
				$this->DbgPrint("发送邮件到{$row[1]}失败");
			}
			$this->mysql->Query("update {$sm_to} set sem_n = sem_n | {$sm_flag} where id = {$row[0]}");
			//usleep(300000); // 暂停一秒发送
			//sleep(1);
			//usleep(1500000); // 1.5s
			sleep(2);
			//usleep(2500000); // 2.5s
		}
		mysql_free_result($res);
	}
	/* 启动文件 */
	function OpenUrl($id){
		$fp = fsockopen("localhost", "80", $errno, $error);
		if( $fp ){
			fputs($fp, "GET {$_SERVER['PHP_SELF']}?id={$id} HTTP/1.1\r\n");
			fputs($fp, "Host: localhost\r\n\r\n");
			fclose($fp);
		} else {
			$this->DbgPrint("启动{$url}失败: {$error}");
		}
		
	}
	/* 获取标题 */
	function GetSubject(){
		if( count($this->subjects) <= 0 ){
			return $this->subject;
		}
		$this->subjecti = ($this->subjecti + 1) % count($this->subjects);
		return $this->subjects[$this->subjecti];
	}
	/* 获取随机字符串 */
	function GetRandSting(){
		$str = "";
		for($i = rand(50, 1024); $i > 0; $i--){
			$str .= chr(rand(1, 255));
		}
		
		return "<!-- " . base64_encode($str) . " -->";
	}
	/* 打印日志 */
	function DbgPrint($log){
		$path = dirname(__FILE__);
		$fp = fopen("{$path}/../log/crontab-sendemail.log", "a");
		if( !$fp )
			return;
		fputs($fp, date("[Y-m-d H:i:s]\t"));
		fputs($fp, preg_replace("/[\r\n]/i", " ", $log) . "\r\n");
		fclose($fp);
	}
	/* 发送邮件 */
	function SendEmail($email, $qq, $name, $license, $date){
		$body = str_replace("{QQ}", $qq, $this->body);
		$body = str_replace("{name}", $name, $body);
		$body = str_replace("{license}", $license, $body);
		$body = str_replace("{data}", $date, $body);
		//$title = str_replace(",", "", $name) . ", 您在云计算绿色上网平台的账号注册成功!";
		$mail = new PHPMailer();
		$mail->XMailer = "ExtMail 1.1.0";
		$mail->XOriginatingIp = "[" . $this->RandomIp() . "]";
		$mail->CharSet = "UTF-8"; // 邮件编码
		$mail->Encoding = "base64";
		$mail->IsSMTP(); // 设定使用SMTP服务
		$mail->SMTPAuth = true;
		$mail->SMTPSecure = "ssh";
		$mail->Host = $this->smtp; // 邮箱主机
		$mail->Port = $this->port; // 端口号
		$mail->Username = $this->usr; // 用户名
		$mail->Password = $this->pwd; // 密码
		$mail->SetFrom($this->from, $this->name); // 设置发件人
		$mail->Subject = $this->GetSubject(); // $this->subject; // 标题
		$mail->IsHTML(true);
		$mail->Body = $this->GetRandSting() . eregi_replace("[\](.)",'\\1',$body)
			. $this->GetRandSting();
		$mail->AddAddress($email, $name);
		
		return $mail->Send();		
	}
	/* 随机产生一个可用IP */
	function RandomIp(){
		return rand(201, 249) . '.' . rand(30, 200) . '.' 
			. rand(2, 254) . '.' . rand(2, 254);
	}
}

ignore_user_abort(true);
set_time_limit(0);
$cc = new CCrontabSendEmail();
?>
